import datetime

from django.db import models
from django.contrib.auth.models import User, AbstractUser

from utils.common.tools import get_account_expire_time
from rbac.models import UserInfo


class UserProfile(UserInfo):
    addr = models.CharField(max_length=64, verbose_name='家庭地址', null=True, blank=True)
    create_nums = models.IntegerField(verbose_name='创建数量', null=True, blank=True)

    def __str__(self):
        """13650300368"""
        return self.username

    class Meta:
        verbose_name_plural = '用户表'

    @classmethod
    def get_user(cls, email):
        return UserProfile.objects.filter(email=email)


class ApplyAccount(models.Model):
    """用户申请的线路账户"""
    name = models.CharField(max_length=32, verbose_name='申请的线路名称', unique=True)
    client_type = models.CharField(max_length=32, verbose_name='客户端类型', default='通用客户端')
    nums = models.IntegerField(verbose_name='申请的线路数量')
    enable_lines = models.TextField(verbose_name='可用线路')
    operator_choices = (
        (0, '移动'),
        (1, '联通'),
        (2, '电信')
    )
    operator = models.PositiveSmallIntegerField(choices=operator_choices, verbose_name='运营商', default=0)
    ip_change_choices = (
        (0, '启用'),
        (1, '禁用')
    )
    ip_change = models.PositiveSmallIntegerField(choices=ip_change_choices, verbose_name='IP 更换设置', default=1,
                                                 null=True, blank=True)
    apply_time = models.DateTimeField(auto_now_add=True, verbose_name='申请时间')
    expire_time = models.DateTimeField(verbose_name='过期时间')
    status = (
        (0, '待审核'),
        (1, '审核通过'),
        (2, '未通过')
    )
    status = models.PositiveSmallIntegerField(choices=status, verbose_name='审核状态', default=0)
    user = models.ForeignKey(UserProfile, verbose_name='所属用户', on_delete=models.CASCADE)

    def __str__(self):
        return self.name

    class Meta:
        verbose_name = '用户线路'
        verbose_name_plural = verbose_name


class Router(models.Model):
    """路由表"""
    name = models.CharField(max_length=32, verbose_name='路由器名称', unique=True)
    mac_addr = models.CharField(max_length=32, verbose_name='路由器 mac 地址', unique=True)
    hmac_addr = models.CharField(max_length=64, verbose_name='hmac 地址', unique=True)
    server_addr = models.CharField(max_length=60, verbose_name='服务器地址', blank=True, null=True)
    tunnel_choices = (
        (0, 'TCP'),
        (1, 'UDP')
    )
    tos_list = models.CharField(verbose_name='初始 tos 列表', max_length=1000)
    tunnel = models.PositiveSmallIntegerField(choices=tunnel_choices, verbose_name='通道', blank=True, null=True,
                                              default=0)
    bind_time = models.DateTimeField(verbose_name='绑定时间', blank=True, null=True)
    create_time = models.DateTimeField(auto_now_add=True, verbose_name='创建时间', blank=True, null=True)

    user = models.ForeignKey(UserProfile, verbose_name='所属用户', on_delete=models.CASCADE)

    def __str__(self):
        """D4EE076B75FE"""
        return self.name

    @classmethod
    def get_mac(cls, mac):
        """获取单个路由"""

        return cls.objects.filter(mac_addr=mac)

    @classmethod
    def get_route(cls, user_id, *args):
        """根据用户 ID，获取路由信息"""
        if len(args) == 2:
            start, end = args[0], args[-1]
            return cls.objects.filter(user_id=user_id)[start:end]

        return cls.objects.filter(user_id=user_id)

    @classmethod
    def get_route_filter(cls, user_id, params, start, end):
        """条件查询"""

        return cls.objects.filter(user_id=user_id).filter(**params)[start:end]

    @classmethod
    def create(cls, route_dic):
        """创建路由"""
        cls.objects.create(**route_dic)

    @classmethod
    def get_tunnel_status(cls, tunnel):
        """返回通道序号"""
        for i in cls.tunnel_choices:
            if i[-1] == tunnel:
                return i[0]

    @classmethod
    def get_mac_hmac_dict(cls, route_obj):
        """返回用户的所有路由器Mac、hamc 地址字典"""
        mac_hmac_dict = {}
        for route in route_obj:
            mac_hmac_dict.update(**{route.mac_addr: route.hmac_addr})

        return mac_hmac_dict

    class Meta:
        verbose_name = '路由器'
        verbose_name_plural = verbose_name


class Terminal(models.Model):
    """终端表"""
    name = models.CharField(max_length=32, verbose_name='终端名称')
    mac_addr = models.CharField(max_length=32, verbose_name='终端 mac 地址', unique=True)
    peer = models.CharField(max_length=128, verbose_name='peer', null=True, blank=True)
    select_lines = models.CharField(max_length=64, verbose_name='用户选择的线路', null=True, blank=True)

    tunnel_status_choices = (
        (0, '启用'),
        (1, '停止')
    )
    tunnel_status = models.PositiveSmallIntegerField(choices=tunnel_status_choices, verbose_name='通道状态', default=1)
    # expire_time = models.DateTimeField(auto_now_add=True, verbose_name='过期时间')
    tos = models.PositiveSmallIntegerField(verbose_name='tos')

    # line = models.ForeignKey('Line', verbose_name='当前线路', on_delete=models.CASCADE)
    user = models.ForeignKey(UserProfile, verbose_name='所属用户', on_delete=models.CASCADE)
    route = models.ForeignKey(Router, verbose_name='所属路由', on_delete=models.CASCADE)
    apply = models.ForeignKey(ApplyAccount, verbose_name='所属账户', on_delete=models.CASCADE)

    def __str__(self):
        """yum1"""
        return self.name

    class Meta:
        verbose_name = '终端设备'
        verbose_name_plural = verbose_name

    @classmethod
    def get_device(cls, user_id, *args):
        """根据用户 ID，获取设备信息"""
        if len(args) == 2:
            start, end = args[0], args[-1]
            return cls.objects.filter(user_id=user_id)[start:end]

        return cls.objects.filter(user_id=user_id)

    @classmethod
    def get_device_filter(cls, user_id, params, start, end):
        """条件查询"""

        return cls.objects.filter(user_id=user_id).filter(**params)[start:end]


    @classmethod
    def get_device_list(cls, device_obj):
        """返回设备列表"""
        device_list = []
        for device in device_obj:
            device_list.append({
                "name": device.name,
                "mac_addr": device.mac_addr,
                "select_lines": device.apply.enable_lines,
                "tunnel_status": device.get_tunnel_status_display(),
                "bind_user": device.apply.name,
                "expire_days": get_account_expire_time(device.apply.expire_time),
                "peer": device.peer,
                "status": "-",
                "public_ip": "-"
            })

        return device_list

    @classmethod
    def total_nums(cls, user_id):
        """返回总数目"""

        return cls.objects.filter(user=user_id).count()


class Line(models.Model):
    """线路表"""
    peer = models.CharField(max_length=128, verbose_name='peer', unique=True)
    province = models.CharField(max_length=32, verbose_name='省份')
    city = models.CharField(max_length=32, verbose_name='城市')
    operator_choices = [
        (0, '移动'),
        (1, '联通'),
        (2, '电信')
    ]

    operator = models.PositiveSmallIntegerField(choices=operator_choices, verbose_name='运营商', default=0)
    ppp_usr = models.CharField(max_length=64, verbose_name='账户名')
    end_point = models.CharField(max_length=64, verbose_name='IP 信息')
    pub_ip = models.CharField(max_length=64, null=True, blank=True, verbose_name='公网IP')
    status_choices = [
        (0, '离线'),
        (1, '在线')
    ]
    status = models.PositiveSmallIntegerField(choices=status_choices, verbose_name='状态', null=True, blank=True)
    netns = models.CharField(max_length=32, verbose_name="命名空间")

    def __str__(self):
        """深圳南山"""
        return '%s%s' % (self.province, self.city)

    class Meta:
        verbose_name = '线路'
        verbose_name_plural = verbose_name


class Server(models.Model):
    """
    服务
    """
    servername = models.CharField(max_length=128, verbose_name='服务', blank=True, unique=True)
    bandwidth = models.CharField(max_length=32, verbose_name='带宽', blank=True)
    Operators = models.CharField(max_length=128, verbose_name='地址', blank=True)
    Country = models.CharField(max_length=128, verbose_name='地址', blank=True)

    @classmethod
    def get_all(cls):
        """获取所有服务器名称"""
        server_list = Server.objects.only('servername')
        server_list = [i.servername for i in server_list]

        return server_list

    def __str__(self):
        return self.servername

    class Meta:
        verbose_name = '服务器'
        verbose_name_plural = verbose_name


class OperationDetail(models.Model):
    """记录操作"""

    operation_type_choice = (
        (0, '绑定路由器'),
        (1, '解绑路由器'),
        (2, '删除路由器'),
    )
    status_choices = ((0, 'success'), (1, 'failed'))
    operation_type = models.PositiveSmallIntegerField(choices=operation_type_choice, verbose_name='操作类型', default=0)
    status = models.PositiveIntegerField(choices=status_choices, default=0, verbose_name='状态')
    result = models.TextField(verbose_name='操作执行结果')
    date = models.DateTimeField(auto_now_add=True, verbose_name='时间')

    user = models.ForeignKey(UserProfile, verbose_name='操作用户', on_delete=models.CASCADE)

    def __str__(self):
        return "{}：{} {}".format(self.user, self.operation_type, self.status)

    class Meta:
        verbose_name = '操作记录'
        verbose_name_plural = verbose_name
